import 'dart:typed_data';

//开灯
openLight(String broad, String led){
  String broadStr = int.parse(broad).toRadixString(16).padLeft(2,'0');
  int broadByte = int.parse("0x$broadStr");
  String ledStr = int.parse(led).toRadixString(16).padLeft(2,'0');
  int ledByte = int.parse("0x$ledStr");
  var bbc = xorComputeResult('9a$broadStr${ledStr}11');
  var array = [0x9a, broadByte, ledByte, 0x11, int.parse('0x$bbc')];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

//关灯
closeLight(String broad, String led){
  String broadStr = int.parse(broad).toRadixString(16).padLeft(2,'0');
  int broadByte = int.parse("0x$broadStr");
  String ledStr = int.parse(led).toRadixString(16).padLeft(2,'0');
  int ledByte = int.parse("0x$ledStr");
  var bbc = xorComputeResult('9b$broadStr${ledStr}11');
  var array = [0x9b, broadByte, ledByte, 0x11, int.parse('0x$bbc')];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}
//FAFB000000000000000000000000000080FCFD
//FAFB000000000000000000000000000080FCFD
getLedCommand(int index, bool isLight) {
  var currentCommand = 'FAFB000000000000000000000000000000FCFD';
  int result1 = (index - 1) ~/ 8;
  int result2 = (index - 1) % 8;
  String pre = currentCommand.substring(0, 4 + result1 * 2);
  String after = currentCommand.substring(6 + result1 * 2, currentCommand.length);

  String orgData = int.parse(currentCommand.substring(4 + result1 * 2, 6 + result1 * 2), radix: 16).toRadixString(2);
  String bData = orgData;
  for (int i = 0; i < 8 - orgData.length; i++) {
    bData = "0$bData";
  }

  if (result2 == 0) {
    if (isLight) {
      bData = "${bData.substring(0, 7)}1";
    } else {
      bData = "${bData.substring(0, 7)}0";
    }
  } else {
    for (int i = 0; i < bData.length; i++) {
      if (i == result2) {
        if (isLight) {
          bData = "${bData.substring(0, 7 - i)}1${bData.substring(8 - i, bData.length)}";
        } else {
          bData = "${bData.substring(0, 7 - i)}0${bData.substring(8 - i, bData.length)}";
        }
        break;
      }
    }
  }
  String newData = int.parse(bData, radix: 2).toRadixString(16);
  if (newData.length == 1) {
    newData = "0$newData";
  }
  currentCommand = pre + newData + after;
  List<int> list = [];
  if(currentCommand.length%2 == 1){
    currentCommand = "${currentCommand}0";
  }
  int length = currentCommand.length;
  int i = 0;
  while(i<length){
    var x = int.parse("0x${currentCommand.substring(i,i+2)}");
    list.add(x);
    i = i+2;
  }
  Uint8List bytes = Uint8List.fromList(list);
  print(bytes);
  return bytes;
}

//设置读写器为ISO14443A模式
setIos1443A(){
  var array = [0x05, 0x00, 0x00, 0x05, 0xDB,0x3A];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

//设置读写器为ISO14443B模式
setIos1443B(){
  var array = [0x05, 0x00, 0x00, 0x09, 0xB7,0xF0];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

//设置读写器为ISO15693模式
setIos15693(){
  var array = [0x05, 0x00, 0x00, 0x06, 0x40,0x08];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}
//读块
readBlock(String uid ){
  List<int> uids = [];
  if(uid.length%2 == 1){
    uid = "${uid}0";
  }
  int length = uid.length;
  int i = 0;
  while(i<length){
    var x = int.parse("0x${uid.substring(i,i+2)}");
    uids.add(x);
    i = i+2;
  }
  var array = [0x0f, 0x00, 0x23, 0x00];
  array.addAll(uids);
  array.addAll([0x00,0x03]);
  var (lsb,msb) = analyzeCRC(array);
  array.addAll([lsb,msb]);
  // var array = [0x07, 0x00, 0x23, 0x05,0x00, 0x08,0xef,0x1b];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

//请求-Request 0600411001A2D3
setRequest(){
  var array = [0x06, 0x00, 0x41, 0x10, 0x01,0xA2,0xD3];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

//读身份证
readerIdentify(){
  var array = [0x05, 0x00, 0x8A, 0x1B, 0x98,0xB2];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

//读读者卡
readReader(){
  var array = [0x06, 0x00, 0x42, 0x10, 0x00,0x4F,0x2D];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

// 0D0073100002FFFFFFFFFFFFDD7D
//选择读者卡
selectReader(uid){
  List<int> uids = [];
  if(uid.length%2 == 1){
    uid = "${uid}0";
  }
  int length = uid.length;
  int i = 0;
  while(i<length){
    var x = int.parse("0x${uid.substring(i,i+2)}");
    uids.add(x);
    i = i+2;
  }
  var array = [0x09, 0x00, 0x43, 0x10];
  array.addAll(uids);
  var (lsb,msb) = analyzeCRC(array);
  array.addAll([lsb,msb]);
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

//认证
authKey(){
  var array = [0x0d, 0x00, 0x73, 0x10, 0x00, 0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xdd,0x7d];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

//读者卡扇区
readReaderBlock(){
  var array = [0x06, 0x00, 0x46, 0x10, 0x08, 0x66,0xc2];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

inventory(){
  var array = [0x05, 0x00, 0x01, 0x06, 0x98,0x11];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

resetToReady(uid){
  List<int> uids = [];
  if(uid.length%2 == 1){
    uid = "${uid}0";
  }
  int length = uid.length;
  int i = 0;
  while(i<length){
    var x = int.parse("0x${uid.substring(i,i+2)}");
    uids.add(x);
    i = i+2;
  }
  var array = [0x0d, 0x00, 0x26, 0x00];
  array.addAll(uids);
  var (lsb,msb) = analyzeCRC(array);
  array.addAll([lsb,msb]);
  // var array = [0x05, 0x00, 0x26, 0x01, 0x1c,0x0b];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}
// 0C0004000F10030103A304D55B
setEasBorrow(){
  var array = [0x0C, 0x00,0x04, 0x00, 0x0F, 0x10, 0x03, 0x01,0x03,0xA3,0x04,0xD5,0x5B];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

setAfiBorrow(uid){
  List<int> uids = [];
  if(uid.length%2 == 1){
    uid = "${uid}0";
  }
  int length = uid.length;
  int i = 0;
  while(i<length){
    var x = int.parse("0x${uid.substring(i,i+2)}");
    uids.add(x);
    i = i+2;
  }
  var array = [0x0e, 0x00, 0x27, 0x00,];
  array.addAll(uids);
  array.addAll([0xc2]);
  var (lsb,msb) = analyzeCRC(array);
  array.addAll([lsb,msb]);
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

setEasReturn(){
  var array = [0x0C, 0x00,0x04, 0x00, 0x0F, 0x10, 0x03, 0x01,0x03,0xA2,0x04,0x0D,0x42];
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

setAfiReturn(uid){
  List<int> uids = [];
  if(uid.length%2 == 1){
    uid = "${uid}0";
  }
  int length = uid.length;
  int i = 0;
  while(i<length){
    var x = int.parse("0x${uid.substring(i,i+2)}");
    uids.add(x);
    i = i+2;
  }
  var array = [0x0e, 0x00, 0x27, 0x00,];
  array.addAll(uids);
  array.addAll([0x07]);
  var (lsb,msb) = analyzeCRC(array);
  array.addAll([lsb,msb]);
  Uint8List bytes = Uint8List.fromList(array);
  print(bytes);
  return bytes;
}

String? xorComputeResult(String para) {
  var dateArr =  [];
  for (int i = 0; i < para.length/2; i++ ) {
    dateArr.add(para.substring(i*2, (i+1)*2));
  }
  for (int i = 1; i < dateArr.length; i++) {
    dateArr[i] = (int.parse(dateArr[i - 1],radix: 16) ^  int.parse(dateArr[i],radix: 16)).toRadixString(16);
    if (i == dateArr.length - 1) {
      return dateArr[i];
    }
  }
  return null;
}

(int, int) analyzeCRC(data) {
  try {
    int i, j;
    int current_crc_value = 0xFFFF;
    for (i = 0; i < data.length; i++) {
      current_crc_value = current_crc_value ^ (data[i] & 0xFF);
      for (j = 0; j < 8; j++) {
        if ((current_crc_value & 0x01) != 0) {
          current_crc_value = (current_crc_value >> 1) ^ 0x8408;
        } else {
          current_crc_value = (current_crc_value >> 1);
        }
      }
    }
    Uint8List dataResult = Uint8List.fromList([0,0]);
    dataResult[0]= (current_crc_value &0xFF);
    dataResult[1]= ((current_crc_value >> 8) & 0xFF);
    int byte1 = int.parse("0x${dataResult[0].toRadixString(16).padLeft(2, '0').toUpperCase()}");
    int byte2 = int.parse("0x${dataResult[1].toRadixString(16).padLeft(2, '0').toUpperCase()}");
    return (byte1,byte2);
  } catch (e ) {
    print(e);
    return (0x00,0x00);
  }
}
